package dj.common.lang.utils;

import com.google.common.base.Strings;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class HttpUtils {

	private static Log logger = LogFactory.getLog(HttpUtils.class);

	public static String httpPost(String urlAddress,
			Map<String, String> paramMap) {

		return httpPost(urlAddress, paramMap, "internal http client");
	}

	public static String httpPostJson(String urlAddress,
			Map<String, String> paramMap, String body) {
		if (paramMap == null) {
			paramMap = new HashMap<String, String>();
		}
		String[] params = new String[paramMap.size()];
		int i = 0;
		for (String paramKey : paramMap.keySet()) {
			String param = paramKey + "=" + paramMap.get(paramKey);
			params[i] = param;
			i++;
		}

		return httpPostJson(urlAddress, params, "internal http client", body);
	}

	public static String httpPost(String urlAddress,
			Map<String, String> paramMap, String userAgent) {
		if (paramMap == null) {
			paramMap = new HashMap<String, String>();
		}
		String[] params = new String[paramMap.size()];
		int i = 0;
		for (String paramKey : paramMap.keySet()) {
			String param = paramKey + "=" + paramMap.get(paramKey);
			params[i] = param;
			i++;
		}
		return httpPost(urlAddress, params, userAgent);
	}

	public static String httpGet(String urlAddress,
			Map<String, String> paramMap, String userAgent) {
		if (paramMap == null) {
			paramMap = new HashMap<String, String>();
		}
		String[] params = new String[paramMap.size()];
		int i = 0;
		for (String paramKey : paramMap.keySet()) {
			String param = paramKey + "=" + paramMap.get(paramKey);
			params[i] = param;
			i++;
		}
		return httpGet(urlAddress, params, userAgent);
	}

	public static String httpPost(String urlAddress, String[] params) {
		return httpPost(urlAddress, params, "internal http client");
	}

	public static String httpPost(String urlAddress, String[] params,
			String userAgent) {
		URL url = null;
		HttpURLConnection con = null;
		BufferedReader in = null;
		StringBuffer result = new StringBuffer();
		try {
			url = new URL(urlAddress);
			// 忽略ssl证书检查
			if ("https".equalsIgnoreCase(url.getProtocol())) {
				SslUtils.ignoreSsl();
			}
			con = (HttpURLConnection) url.openConnection();
			con.setUseCaches(false);
			con.setDoOutput(true);
			con.setRequestMethod("POST");
			con.setRequestProperty("User-Agent", userAgent);
			con.setRequestProperty("Content-Type",
					"application/x-www-form-urlencoded; charset=UTF-8");
			String paramsTemp = "";
			for (String param : params) {
				if (param != null && !"".equals(param.trim())) {
					paramsTemp += "&" + param;
				}
			}
			paramsTemp.substring(1);
			byte[] b = paramsTemp.getBytes();
			OutputStream outputStream = con.getOutputStream();
			outputStream.write(b, 0, b.length);
			outputStream.flush();
			outputStream.close();
			in = new BufferedReader(new InputStreamReader(con.getInputStream(),
					"utf-8"));
			while (true) {
				String line = in.readLine();
				if (line == null) {
					break;
				} else {
					result.append(line);
				}
			}
		} catch (Exception e) {
			logger.error("ERROR:", e);
		} finally {
			try {
				if (in != null) {
					in.close();
				}
				if (con != null) {
					con.disconnect();
				}
			} catch (IOException e) {
				logger.error("ERROR:", e);
			}
		}
		return result.toString();
	}

	public static String httpPostJson(String urlAddress, String[] params,
			String userAgent, String body) {
		URL url = null;
		HttpURLConnection con = null;
		BufferedReader in = null;
		StringBuffer result = new StringBuffer();
		try {
			String paramsTemp = "";
			if (params != null && params.length>0 ) {
				for (String param : params) {
					if (param != null && !"".equals(param.trim())) {
						paramsTemp += "&" + param;
					}
				}
				paramsTemp = paramsTemp.substring(1);
			}
			if (urlAddress.contains("?")) {
				logger.info("post消息：" + urlAddress + "&" + paramsTemp
						+ ":userAgent:" + userAgent + "；body:" + body);
				url = new URL(urlAddress + "&" + paramsTemp);
			} else {
				logger.info("post消息：" + urlAddress + "?" + paramsTemp
						+ ":userAgent:" + userAgent + "；body:" + body);
				url = new URL(urlAddress + "?" + paramsTemp);
			}
			// 忽略ssl证书检查
			if ("https".equalsIgnoreCase(url.getProtocol())) {
				SslUtils.ignoreSsl();
			}

			con = (HttpURLConnection) url.openConnection();
			con.setUseCaches(false);
			con.setDoOutput(true);
			con.setRequestMethod("POST");
			con.setRequestProperty("User-Agent", userAgent);
			con.setRequestProperty("Content-Type",
					"application/json; charset=UTF-8");

			OutputStream outputStream = con.getOutputStream();
			if (!Strings.isNullOrEmpty(body)) {
				outputStream.write(body.getBytes("utf-8"));
			}
			outputStream.flush();
			outputStream.close();
			in = new BufferedReader(new InputStreamReader(con.getInputStream(),
					"utf-8"));
			while (true) {
				String line = in.readLine();
				if (line == null) {
					break;
				} else {
					result.append(line);
				}
			}
		} catch (Exception e) {
			logger.error("ERROR:", e);
		} finally {
			try {
				if (in != null) {
					in.close();
				}
				if (con != null) {
					con.disconnect();
				}
			} catch (IOException e) {
				logger.error("ERROR:", e);
			}
		}
		return result.toString();
	}

	public static String httpGet(String urlAddress) {
		String[] params = null;
		return httpGet(urlAddress, params, "");
	}

	public static int httpGetStatusCode(String urlAddress) {
		URL url = null;
		HttpURLConnection con = null;
		int statusCode = -1; // invalid value
		try {
			url = new URL(urlAddress);
			con = (HttpURLConnection) url.openConnection();
			con.setUseCaches(false);
			con.setDoOutput(true);
			con.setRequestMethod("GET");
			statusCode = con.getResponseCode();

		} catch (IOException e) {
			logger.error("ERROR:", e);
			return -1;
		} finally {
			if (con != null) {
				con.disconnect();
			}
		}
		return statusCode;
	}


	public static String httpGetImage(String urlAddress,String rootPath) {
		if (StringUtils.isBlank(urlAddress)){
			return null;
		}
		String fileName = "";
		String[] split = urlAddress.split("/");
		if (split != null && split.length > 0){
			fileName = split[split.length -1];
		}

		URL url = null;
		HttpURLConnection con = null;
		InputStream inputStream = null;
		OutputStream outputStream = null;

		List<Byte> data = new ArrayList<Byte>();
		try {
			url = new URL(urlAddress);
			// 忽略ssl证书检查
			if ("https".equalsIgnoreCase(url.getProtocol())) {
				SslUtils.ignoreSsl();
			}
			con = (HttpURLConnection) url.openConnection();
			con.setUseCaches(false);
			con.setDoOutput(true);
			con.setRequestMethod("GET");
			inputStream = con.getInputStream();

			//创建文件的根目录
			CreateDir(rootPath);
			File file = null;
			//创建文件
			file = CreateFile(rootPath + fileName);
			outputStream = new FileOutputStream(file);
			//使用byte【】数组来接收输入流
			byte buffer[] = new byte[10 * 1024];
			int length = 0;

			while ((length = inputStream.read(buffer)) != -1) {
				outputStream.write(buffer, 0, length);
			}
			return file.getAbsolutePath();

		} catch (Exception e) {
			logger.error("【httpGetImage】 ERROR:", e);
		} finally {
			try {
				if (inputStream != null) {
					inputStream.close();
				}
				if (outputStream != null) {
					outputStream.close();
				}
				if (con != null) {
					con.disconnect();
				}
			} catch (IOException e) {
				logger.error("【httpGetImage】ERROR:", e);
			}
		}
		return null;
	}


	private static boolean  isExistFile(String s) {
		File file = new File(s);
		if (file.exists()) {
			return true;
		}
		return false;
	}

	private static boolean CreateDir(String rootPath) {
		File file = new File(rootPath);
		if (!file.exists()) {
			boolean isCreateDir = file.mkdir();
			return isCreateDir;
		}
		return false;

	}

	private static File CreateFile(String s) {
		File file = new File(s);
		try {
			if(!file.exists()) {
				file.createNewFile();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return file;

	}


	public static String httpGet(String urlAddress, String[] params,
			String userAgent) {
		URL url = null;
		HttpURLConnection con = null;
		BufferedReader in = null;
		StringBuffer result = new StringBuffer();
		try {
			String paramsTemp = "";
			if (params != null) {
				for (String param : params) {
					if (param != null && !"".equals(param.trim())) {
						paramsTemp += "&" + param;
					}
				}
				paramsTemp = paramsTemp.substring(1);
			}
			if (urlAddress.contains("?")) {
				url = new URL(urlAddress + "&" + paramsTemp);
			} else {
				url = new URL(urlAddress + "?" + paramsTemp);
			}
			// 忽略ssl证书检查
			if ("https".equalsIgnoreCase(url.getProtocol())) {
				SslUtils.ignoreSsl();
			}
			con = (HttpURLConnection) url.openConnection();
			con.setUseCaches(false);
			con.setDoOutput(true);
			con.setRequestMethod("GET");
			con.setRequestProperty("User-Agent", userAgent);
			// con.setRequestProperty(
			// "User-Agent",
			// "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36");
			// con.setRequestProperty("Content-Type",
			// "application/x-www-form-urlencoded; charset=UTF-8");
			in = new BufferedReader(new InputStreamReader(con.getInputStream(),
					"utf-8"));
			while (true) {
				String line = in.readLine();
				if (line == null) {
					break;
				} else {
					result.append(line);
				}
			}
		} catch (Exception e) {
			logger.error("ERROR:", e);
			result.append("-1");
		} finally {
			try {
				if (in != null) {
					in.close();
				}
				if (con != null) {
					con.disconnect();
				}
			} catch (IOException e) {
				logger.error("ERROR:", e);
				result.append("-1");
			}
		}
		return result.toString();
	}

	public static String httpUploadFile(String urlAddress, String filePath,
			String contentType) {
		URL url = null;
		HttpURLConnection con = null;
		BufferedReader in = null;
		StringBuffer result = new StringBuffer();
		try {
			url = new URL(urlAddress);
			con = (HttpURLConnection) url.openConnection();
			con.setUseCaches(false);
			con.setDoOutput(true);
			con.setRequestMethod("POST");
			con.setRequestProperty("User-Agent", "ZingUploader");
			con.setRequestProperty("Content-Type", contentType);

			OutputStream outputStream = con.getOutputStream();
			BufferedInputStream bis = new BufferedInputStream(
					new FileInputStream(filePath));
			byte[] b = new byte[4096];
			while (bis.read(b) >= 0) {
				outputStream.write(b);
			}

			outputStream.flush();
			outputStream.close();
			bis.close();
			in = new BufferedReader(new InputStreamReader(con.getInputStream(),
					"utf-8"));
			while (true) {
				String line = in.readLine();
				if (line == null) {
					break;
				} else {
					result.append(line);
				}
			}
		} catch (IOException e) {
			logger.error("ERROR:", e);
		} finally {
			try {
				if (in != null) {
					in.close();
				}
				if (con != null) {
					con.disconnect();
				}
			} catch (IOException e) {
				logger.error("ERROR:", e);
			}
		}
		return result.toString();
	}

	public static String httpDelete(String urlAddress,
									Map<String, String> paramMap, String userAgent) {
		if (paramMap == null) {
			paramMap = new HashMap<String, String>();
		}
		String[] params = new String[paramMap.size()];
		int i = 0;
		for (String paramKey : paramMap.keySet()) {
			String param = paramKey + "=" + paramMap.get(paramKey);
			params[i] = param;
			i++;
		}
		return httpDelete(urlAddress, params, userAgent);
	}

	public static String httpDelete(String urlAddress, String[] params,
									String userAgent) {
		URL url = null;
		HttpURLConnection con = null;
		BufferedReader in = null;
		StringBuffer result = new StringBuffer();
		try {
			String paramsTemp = "";
			if (params != null) {
				for (String param : params) {
					if (param != null && !"".equals(param.trim())) {
						paramsTemp += "&" + param;
					}
				}
				paramsTemp = paramsTemp.substring(1);
			}
			if (urlAddress.contains("?")) {
				url = new URL(urlAddress + "&" + paramsTemp);
			} else {
				url = new URL(urlAddress + "?" + paramsTemp);
			}
			// 忽略ssl证书检查
			if ("https".equalsIgnoreCase(url.getProtocol())) {
				SslUtils.ignoreSsl();
			}
			con = (HttpURLConnection) url.openConnection();
			con.setUseCaches(false);
			con.setDoOutput(true);
			con.setRequestMethod("DELETE");
			con.setRequestProperty("User-Agent", userAgent);
			in = new BufferedReader(new InputStreamReader(con.getInputStream(),
					"utf-8"));
			while (true) {
				String line = in.readLine();
				if (line == null) {
					break;
				} else {
					result.append(line);
				}
			}
		} catch (Exception e) {
			logger.error("ERROR:", e);
			result.append("-1");
		} finally {
			try {
				if (in != null) {
					in.close();
				}
				if (con != null) {
					con.disconnect();
				}
			} catch (IOException e) {
				logger.error("ERROR:", e);
				result.append("-1");
			}
		}
		return result.toString();
	}

    public static String getIPAddress(HttpServletRequest request) {
        String ip = null;

        //X-Forwarded-For：Squid 服务代理
        String ipAddresses = request.getHeader("X-Forwarded-For");

        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //Proxy-Client-IP：apache 服务代理
            ipAddresses = request.getHeader("Proxy-Client-IP");
        }

        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //WL-Proxy-Client-IP：weblogic 服务代理
            ipAddresses = request.getHeader("WL-Proxy-Client-IP");
        }

        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //HTTP_CLIENT_IP：有些代理服务器
            ipAddresses = request.getHeader("HTTP_CLIENT_IP");
        }

        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //X-Real-IP：nginx服务代理
            ipAddresses = request.getHeader("X-Real-IP");
        }

        //有些网络通过多层代理，那么获取到的ip就会有多个，一般都是通过逗号（,）分割开来，并且第一个ip为客户端的真实IP
        if (ipAddresses != null && ipAddresses.length() != 0) {
            ip = ipAddresses.split(",")[0];
        }

        //还是不能获取到，最后再通过request.getRemoteAddr();获取
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}
